home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume24 / faxpax / part03 < prev    next >
Encoding:
Internet Message Format  |  1991-03-12  |  53.8 KB

  1. Subject:  v24i041:  Email fax-sending package, Part03/05
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 516a90d5 4fc99e87 0f262bf5 b7da1c66
  5.  
  6. Submitted-by: klaus u schallhorn <cnix!klaus>
  7. Posting-number: Volume 24, Issue 41
  8. Archive-name: faxpax/part03
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then feed it
  12. # into a shell via "sh file" or similar.  To overwrite existing files,
  13. # type "sh file -c".
  14. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  15. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  16. # Contents:  faxclient/fax.c faxhost/spool.fax.c sample.fax.aliases
  17. #   writefax.man
  18. # Wrapped by rsalz@litchi.bbn.com on Wed Mar 13 14:08:02 1991
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. echo If this archive is complete, you will see the following message:
  21. echo '          "shar: End of archive 3 (of 5)."'
  22. if test -f 'faxclient/fax.c' -a "${1}" != "-c" ; then 
  23.   echo shar: Will not clobber existing file \"'faxclient/fax.c'\"
  24. else
  25.   echo shar: Extracting \"'faxclient/fax.c'\" \(14931 characters\)
  26.   sed "s/^X//" >'faxclient/fax.c' <<'END_OF_FILE'
  27. X#include <stdio.h>
  28. X#include <malloc.h>
  29. X#include <unistd.h>
  30. X#include <pwd.h>
  31. X#include <string.h>
  32. X#include <signal.h>
  33. X#include <sys/time.h>
  34. X#include <sys/stat.h>
  35. X
  36. X#include "../faxconfig.h"
  37. X
  38. X#ifdef    NETWIDE_FAX
  39. X#include <sys/types.h>
  40. X#include <sys/socket.h>
  41. X#include <netinet/in.h>
  42. X#include <netdb.h>
  43. X#endif
  44. X
  45. X
  46. X/*
  47. X    fax.c
  48. X
  49. X    accept fax from user.
  50. X
  51. X    src is either a file or stdin, dest is spooler somewhere on the net.
  52. X    do some parsing && error checking before we invoke the spooler.
  53. X    allow aliases and lists for destination fax.
  54. X    argv[1] must be either a phone no [no alpha, just digits && ispunct()],
  55. X    an alias [as found in $HOME/fax.aliases], or name of a fax list file.
  56. X
  57. X    format of alias file:
  58. X    =====================
  59. X    alias   phone no   ftao, starts with a colon         optional comment
  60. X    ---------------------------------------------------------------------
  61. X    fred    12345678   :for the attention of fred bloggs # comment
  62. X    bill    98765
  63. X    joe    7654323       :The Lady in Pnik
  64. X
  65. X    format of fax list
  66. X    ==================
  67. X    phone no   ftao, starts with a colon        opt. comment    
  68. X    ------------------------------------------------------------
  69. X    12345678   :for the attention of fred bloggs    # comment
  70. X    9274356                        # no ftao
  71. X    87340875   :z. Hd. Herrn Meier            # needs it on time
  72. X
  73. X    first released version 0.99 [desperado version]
  74. X    cleaned up Jan 21st '91,
  75. X    Copyright (C) 1991, klaus schallhorn, klaus@cnix.uucp
  76. X
  77. X    Permission to use, copy, modify, and distribute this software 
  78. X    and its documentation for any purpose and without fee is hereby 
  79. X    granted, provided that the above copyright notice appear in 
  80. X    all copies and that both that copyright notice and this permission 
  81. X    notice appear in supporting documentation. 
  82. X
  83. X    This software is provided "as is" without express or implied warranty.
  84. X*/
  85. X
  86. Xextern    int errno;
  87. X
  88. Xchar    me[80], tmpname[256], io[256], *hpfont, **phone, **ftao, *fname,
  89. X    *retfax, *home;
  90. Xchar    *get_aka(), *get_list(), *getenv();
  91. X
  92. Xstruct    passwd *pwentry, *getpwuid();
  93. Xint    now, mail, hires, entries, alloced, save, broken;
  94. XFILE    *collect_msg();
  95. Xvoid    breakread();
  96. X
  97. X
  98. Xnoalpha(s)    /* allow digits and ispunct() in phone nos */
  99. Xchar *s;
  100. X{
  101. X    while (*s)
  102. X    {
  103. X        if (isalpha(*s))
  104. X            return(FALSE);
  105. X        ++s;
  106. X    }
  107. X    return(TRUE);
  108. X}
  109. Xfstbyte(s,skip)
  110. Xchar *s;
  111. Xint skip;
  112. X{
  113. X    s += skip;
  114. X    while (*s && isspace(*s))
  115. X    {
  116. X        ++skip;
  117. X        ++s;
  118. X    }
  119. X    return(skip);
  120. X}
  121. Xvoid get_rc()    /* read user defaults stashed in $HOME/.faxrc */
  122. X{
  123. X    FILE *rc;
  124. X    char *ptr, *save_str();
  125. X
  126. X    if (*home == '/' && *(home+1) == '\0')
  127. X        strcpy(io,"/.faxrc");
  128. X    else sprintf(io,"%s/.faxrc",home);
  129. X
  130. X    if ((rc = fopen(io, "r")) == NULL)
  131. X        return;
  132. X
  133. X    while (fgets(io, 248, rc) != NULL)
  134. X    {
  135. X        if (io[0] == '#')
  136. X            continue;
  137. X
  138. X        if ((ptr = strchr(io, '\n')) != NULL)
  139. X            *ptr = '\0';
  140. X        ptr = io;
  141. X        if (!strncmp(io, "font", 4))
  142. X        {
  143. X            ptr += fstbyte(io, 4);
  144. X            hpfont = save_str(ptr);
  145. X        }
  146. X        else if (!strncmp(io, "resolution", 10))
  147. X        {
  148. X            ptr += fstbyte(io, 10);
  149. X            hires = get_bool(ptr, "high");
  150. X        }
  151. X        else if (!strncmp(io, "mail", 4))    /* mail success msg */
  152. X        {
  153. X            ptr += fstbyte(io, 4);
  154. X            mail = get_bool(ptr, "true");
  155. X        }
  156. X        else if (!strncmp(io, "now", 3))    /* send now */
  157. X        {
  158. X            ptr += fstbyte(io, 3);
  159. X            now = get_bool(ptr, "true");
  160. X        }
  161. X        else if (!strncmp(io, "save", 4))    /* save in $HOME/FaxSent */
  162. X        {
  163. X            ptr += fstbyte(io, 4);
  164. X            save = get_bool(ptr, "true");
  165. X        }
  166. X        else if (!strncmp(io, "retfax", 6))    /* return faxno */
  167. X        {
  168. X            ptr += fstbyte(io, 6);
  169. X            retfax = save_str(ptr);
  170. X        }
  171. X    }
  172. X}
  173. Xchar *save_str(s)
  174. Xchar *s;
  175. X{
  176. X    char *p;
  177. X
  178. X    if ((p = malloc(1+strlen(s))) == NULL)
  179. X    {
  180. X        fprintf(stderr,"can't allocate memory\n");
  181. X        exit(1);
  182. X    }
  183. X    strcpy(p, s);
  184. X    return(p);
  185. X}
  186. Xget_bool(from,true)
  187. Xchar *from, *true;
  188. X{
  189. X    if (!strncmp(from, true, strlen(true)))
  190. X        return(TRUE);
  191. X    return(FALSE);
  192. X}
  193. X
  194. Xchar *get_aka(s) /* allocate and return a phone number for an alias */
  195. Xchar *s;
  196. X{
  197. X    char tmp[256], phoneno[80], alias[80], *ptr, *eptr;
  198. X    FILE *fp;
  199. X    int len, found;
  200. X
  201. X    errno = 0;
  202. X    if (*home == '/' && *(home+1) == '\0')
  203. X        strcpy(tmp,"/fax.aliases");
  204. X    else sprintf(tmp,"%s/fax.aliases",home);
  205. X
  206. X    len = strlen(s);
  207. X    found = 0;
  208. X    if ((fp = fopen(tmp, "r")) != NULL)
  209. X    {
  210. X        while (fgets(tmp, 248, fp) != NULL)
  211. X        {
  212. X            if (sscanf(tmp, "%s %s",alias,phoneno) < 2)
  213. X                continue;
  214. X            if (!strcmp(s, alias, len))
  215. X            {
  216. X                found = TRUE;
  217. X                break;
  218. X            }
  219. X        }
  220. X        fclose(fp);
  221. X    }
  222. X    if (!found)    /* check if there's a file by that name */
  223. X    {
  224. X        if ((phone[0] = get_list(s)) == NULL)
  225. X        {
  226. X            fprintf(stderr,"no alias for %s, no faxlist %s\n",s,s);
  227. X            return(NULL);
  228. X        }
  229. X        return(phone[0]);
  230. X    }
  231. X
  232. X    if ((phone[0] = malloc(1+strlen(phoneno))) == NULL)
  233. X    {
  234. X        fprintf(stderr,"can't allocate memory\n");
  235. X        return(NULL);
  236. X    }
  237. X    strcpy(phone[0], phoneno);
  238. X    if ((ptr = strchr(tmp, ':')) != NULL)
  239. X    {
  240. X        if ((eptr = strrchr(tmp, '#')) != NULL)
  241. X            *eptr = '\0';
  242. X        if ((ftao[0] = malloc(1+strlen(++ptr))) == NULL)
  243. X        {
  244. X            fprintf(stderr,"can't allocate memory\n");
  245. X            return(NULL);
  246. X        }
  247. X        strcpy(ftao[0], ptr);
  248. X    }
  249. X    ++entries;
  250. X    return(phone[0]);
  251. X}
  252. Xchar *get_list(name)    /* read and allocate a list of phone nos */
  253. Xchar *name;
  254. X{
  255. X    static char tmp[256], phoneno[80], *fname0, *fname1, *ptr, *eptr;
  256. X    FILE *fp;
  257. X    int i;
  258. X
  259. X        /* check listnames: 
  260. X            if name[0] == '/', use absolute path
  261. X            else check ".", then $HOME
  262. X        */
  263. X    errno = 0;
  264. X    if (*name == '/')
  265. X    {
  266. X        fname0 = name;
  267. X        fname1 = NULL;
  268. X    }
  269. X    else
  270. X    {
  271. X        if (*home == '/' && *(home+1) == '\0')
  272. X            sprintf(tmp,"/%s",name);
  273. X        else sprintf(tmp,"%s/%s",home,name);
  274. X        fname0 = name;
  275. X        fname1 = tmp;
  276. X    }
  277. X
  278. X    if ((fp = fopen(fname0, "r")) == NULL)
  279. X        if ((fp = fopen(fname1, "r")) == NULL)
  280. X            return(NULL);
  281. X
  282. X    while (fgets(tmp, 248, fp) != NULL)
  283. X    {
  284. X        if (sscanf(tmp, "%s",phoneno) < 1 || tmp[0] == '#')
  285. X            continue;
  286. X
  287. X        if ((phone[entries] = malloc(1+strlen(phoneno))) == NULL)
  288. X        {
  289. X            fprintf(stderr,"can't allocate memory\n");
  290. X            return(NULL);
  291. X        }
  292. X        strcpy(phone[entries], phoneno);
  293. X
  294. X        if ((ptr = strchr(tmp, ':')) != NULL)
  295. X        {
  296. X            if ((eptr = strrchr(tmp, '#')) != NULL)
  297. X                *eptr = '\0';
  298. X            if ((ftao[entries] = malloc(1+strlen(++ptr))) == NULL)
  299. X            {
  300. X                fprintf(stderr,"can't allocate memory\n");
  301. X                return(NULL);
  302. X            }
  303. X            strcpy(ftao[entries], ptr);
  304. X        }
  305. X        else ftao[entries] = NULL;
  306. X
  307. X        if (++entries == alloced) /* reshuffle base ptrs */
  308. X        {
  309. X            if ((phone = (char **)realloc(phone,
  310. X                ((alloced + 8) * sizeof(char *)))) == NULL)
  311. X            {
  312. X                fprintf(stderr,"can't allocate memory\n");
  313. X                return(NULL);
  314. X            }
  315. X                /* increment alloced now */
  316. X            if ((ftao = (char **)realloc(ftao,
  317. X                ((alloced += 8) * sizeof(char *)))) == NULL)
  318. X            {
  319. X                fprintf(stderr,"can't allocate memory\n");
  320. X                return(NULL);
  321. X            }
  322. X        }
  323. X    }
  324. X    fclose(fp);
  325. X    for (i=entries; i<alloced; i++)
  326. X        phone[i] = ftao[i] = NULL;
  327. X    return(phone[0]);
  328. X}
  329. X
  330. Xmain(argc,argv)
  331. Xint argc;
  332. Xchar *argv[];
  333. X{
  334. X#ifdef    NETWIDE_FAX
  335. X    struct hostent *hent;
  336. X    struct sockaddr_in sin;
  337. X    struct servent *sent;
  338. X    int s;
  339. X#endif
  340. X    int i, ac, piped, type;
  341. X    FILE *ofp, *faxfp;
  342. X
  343. X    if (argc == 1)
  344. X    {
  345. X        fprintf(stderr,"fax phone [file], -opt for options\n");
  346. X        exit(1);
  347. X    }
  348. X
  349. X    if ((home = getenv("HOME")) == NULL)
  350. X    {
  351. X        fprintf(stderr,"you're homeless\n");
  352. X        exit(1);
  353. X    }
  354. X    if (argc == 2 && (!strncmp(argv[1], "-opt", 4)))    /* usage */
  355. X        usage();
  356. X
  357. X    if ((pwentry = getpwuid(getuid())) == NULL)
  358. X    {
  359. X        fprintf(stderr,"you don't exist {%d}\n",errno);
  360. X        exit(1);
  361. X    }
  362. X    setuid(getuid());
  363. X    setgid(getgid());
  364. X
  365. X    piped = 0;
  366. X    now = mail = hires = save = 0;
  367. X    type = ASCII;
  368. X    hpfont = retfax = fname = (char *)NULL;
  369. X    ofp = faxfp = (FILE *)NULL;
  370. X    me[0] = tmpname[0] = '\0';
  371. X
  372. X    if ((phone = (char **)malloc(8*sizeof(char *))) == NULL)
  373. X        fprintf(stderr,"can't allocate memory");
  374. X    if ((ftao = (char **)malloc(8*sizeof(char *))) == NULL)
  375. X        fprintf(stderr,"can't allocate memory");
  376. X    for (i=0; i<8; i++)
  377. X        phone[i] = ftao[i] = NULL;
  378. X    alloced = 8;
  379. X    entries = 0;
  380. X
  381. X    get_rc();
  382. X
  383. X    for (ac=1; ac<argc; ac++)
  384. X    {
  385. X        if (phone[0] == NULL) /* first av[] is phone no, alias or list */
  386. X        {
  387. X            if (noalpha(argv[ac]))
  388. X            {
  389. X                phone[0] = argv[ac];
  390. X                entries = 1;
  391. X            }
  392. X            else if ((phone[0] = get_aka(argv[ac])) == NULL)
  393. X                exit(1);
  394. X        }
  395. X        else if (!strncmp(argv[ac], "-a", 2))    /* attn: fred bloggs */
  396. X        {
  397. X            ftao[0] = &argv[ac][2];
  398. X            entries = 1;
  399. X        }
  400. X        else if (!strncmp(argv[ac], "-f", 2))    /* use hp compat font */
  401. X            hpfont = &argv[ac][2];
  402. X        else if (!strncmp(argv[ac], "-h", 2))    /* high res, expensive */
  403. X            hires = TRUE;
  404. X        else if (!strncmp(argv[ac], "-l", 2))    /* low res */
  405. X            hires = FALSE;
  406. X        else if (!strncmp(argv[ac], "-m", 2))    /* mail success msg */
  407. X            mail = TRUE;
  408. X        else if (!strncmp(argv[ac], "-n", 2))    /* send now */
  409. X            now = TRUE;
  410. X        else if (!strncmp(argv[ac], "-r", 2))    /* return faxno */
  411. X            retfax = &argv[ac][2];
  412. X        else if (!strncmp(argv[ac], "-s", 2))    /* save in $HOME/FaxSent */
  413. X            save = TRUE;
  414. X        else fname = argv[ac];
  415. X    }
  416. X
  417. X    if (phone[0] == NULL)
  418. X    {
  419. X        fprintf(stderr,"no recipient\n");
  420. X        exit(1);
  421. X    }
  422. X    if (fname == NULL)
  423. X    {
  424. X        if (isatty(fileno(stdin)))
  425. X            fprintf(stderr,"reading stdin:\n");
  426. X        if ((faxfp = collect_msg()) == NULL)
  427. X            exit(1);
  428. X    }
  429. X    else if ((faxfp = fopen(fname, "r")) == NULL)
  430. X    {
  431. X        fprintf(stderr,"can't open %s for input\n",fname);
  432. X        exit(1);
  433. X    }
  434. X
  435. X#ifdef    NETWIDE_FAX
  436. X                /* that's me, with a little bit of luck */
  437. X    if (gethostname(me, 80))
  438. X    {
  439. X        fprintf(stderr,"I don't exist {%d}\n",errno);
  440. X        exit(1);
  441. X    }
  442. X
  443. X    if ((hent = gethostbyname(FAXHOST)) == NULL)
  444. X    {
  445. X        fprintf(stderr,"%s not known {%d}\n",FAXHOST,errno);
  446. X        exit(1);
  447. X    }
  448. X
  449. X    if (strcmp(me, hent->h_name))        /* FAXHOST != me */
  450. X    {
  451. X        if ((sent = getservbyname(FAXSERVER, "tcp")) == NULL)
  452. X        {
  453. X            fprintf(stderr,"%s service not known {%d}\n",FAXSERVER,errno);
  454. X            exit(1);
  455. X        }
  456. X
  457. X        /* grab a socket */
  458. X        if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  459. X        {
  460. X            fprintf(stderr," can't grab a socket {%d}\n",errno);
  461. X            exit(1);
  462. X        }
  463. X        sin.sin_family = AF_INET;
  464. X        sin.sin_port = htons(sent->s_port);
  465. X        bcopy(hent->h_addr, &sin.sin_addr, hent->h_length);
  466. X
  467. X        /* now try to connect */
  468. X        if (connect(s, &sin, sizeof(sin)) < 0)
  469. X        {
  470. X            fprintf(stderr,"can't connect {%d}\n",errno);
  471. X            exit(1);
  472. X        }
  473. X        if ((ofp = fdopen(s, "w")) == NULL)
  474. X        {
  475. X            fprintf(stderr,"can't open socket for buffered write {%d}\n",errno);
  476. X            exit(1);
  477. X        }
  478. X    }
  479. X    else
  480. X#endif
  481. X    {
  482. X        char ppath[128];
  483. X
  484. X        me[0] = '\0';    /* running on faxhost */
  485. X        sprintf(ppath,"%s/%s",FAXLIB,FAXSERVER);
  486. X        if ((ofp = popen(ppath, "w")) == NULL)
  487. X        {
  488. X            fprintf(stderr,"can't pipe to %s {%d}\n",ppath,errno);
  489. X            exit(1);
  490. X        }
  491. X        piped = TRUE;
  492. X    }
  493. X
  494. X/* do something useful */
  495. X
  496. X    ac = spoolfax(me, pwentry->pw_name, ofp, faxfp, type);
  497. X
  498. X    if (piped)
  499. X        pclose(ofp);
  500. X#ifdef    NETWIDE_FAX
  501. X    else close(s);
  502. X#endif
  503. X    if (save)
  504. X        savefax((fname==NULL)?tmpname:fname);
  505. X
  506. X    if (tmpname[0])
  507. X        unlink(tmpname);
  508. X    exit(ac);
  509. X}
  510. X
  511. Xspoolfax(host, user, outfp, infp, ftype)
  512. Xchar *host, *user;
  513. XFILE *outfp, *infp;
  514. Xint ftype;
  515. X{
  516. X    char tmp[256];
  517. X    int nread, i;
  518. X
  519. X    if (*host)
  520. X        sprintf(tmp,"%s@%s",user,host);
  521. X    else strcpy(tmp,user);
  522. X
  523. X#define    write_err()    fprintf(stderr,"can't spool fax {%d}\n",errno)
  524. X
  525. X    errno = 0;
  526. X    if (fprintf(outfp,"user %s\n",tmp) == EOF)
  527. X        return(write_err());
  528. X    if (fprintf(outfp,"uid %d\n",getuid()) == EOF)
  529. X        return(write_err());
  530. X
  531. X    if (fprintf(outfp,"now %d\n",now) == EOF)
  532. X        return(write_err());
  533. X    if (fprintf(outfp,"mail %d\n",mail) == EOF)
  534. X        return(write_err());
  535. X    if (fprintf(outfp,"type %d\n",ftype) == EOF)
  536. X        return(write_err());
  537. X    if (fprintf(outfp,"hires %d\n",hires) == EOF)
  538. X        return(write_err());
  539. X
  540. X    if (fprintf(outfp,"font %s\n",(hpfont)?hpfont:"none") == EOF)
  541. X        return(write_err());
  542. X
  543. X    if (fprintf(outfp,"retfax %s\n",(retfax)?retfax:"none") == EOF)
  544. X        return(write_err());
  545. X
  546. X    fprintf(outfp,"#\n");    /* marker for spoolfax */
  547. X
  548. X    for (i=0; i<entries; i++)
  549. X    {
  550. X        if (fprintf(outfp,"phone %s",phone[i]) == EOF)
  551. X            return(write_err());
  552. X        if (ftao[i])
  553. X        {
  554. X            if (fprintf(outfp," :%s",ftao[i]) == EOF)
  555. X                return(write_err());
  556. X        }
  557. X        fprintf(outfp,"\n");
  558. X    }
  559. X    if (fprintf(outfp,"data\n") == EOF)
  560. X        return(write_err());
  561. X
  562. X    while ((nread = fread(tmp, 1, 256, infp)) > 0)
  563. X        if (fwrite(tmp, 1, nread, outfp) != nread)
  564. X            return(write_err());
  565. X    fflush(outfp);
  566. X    return(0);
  567. X}
  568. Xvoid breakread()
  569. X{
  570. X    broken = TRUE;
  571. X}
  572. X
  573. XFILE *collect_msg()
  574. X{
  575. X    static FILE *fp;
  576. X    int written, tty;
  577. X
  578. X    broken = written = 0;
  579. X    signal(SIGINT, breakread);
  580. X    siginterrupt(SIGINT, 1);    /* interrupt sys calls */
  581. X
  582. X    tty = isatty(fileno(stdin));
  583. X    if (*home == '/' && *(home+1) == '\0')
  584. X        strcpy(tmpname,"/.infax.XXXXXX");
  585. X    else sprintf(tmpname,"%s/.infax.XXXXXX",home);
  586. X    mktemp(tmpname);
  587. X    if ((fp = fopen(tmpname, "w+")) == NULL)
  588. X    {
  589. X        fprintf(stderr,"can't create tmp file\n");
  590. X        return(NULL);
  591. X    }
  592. X    while (fgets(io, 248, stdin) != NULL)
  593. X    {
  594. X        if (broken)
  595. X        {
  596. X            written = 0;
  597. X            break;
  598. X        }
  599. X        if (io[0] == '.' && tty)
  600. X            break;
  601. X        else if (io[0] == '~' && io[1] == 'v' && tty)
  602. X        {
  603. X            fclose(fp);
  604. X            edit(tmpname);
  605. X            if ((fp = fopen(tmpname, "a+")) == NULL)
  606. X            {
  607. X                fprintf(stderr,"no tmp file ?\n");
  608. X                return(NULL);
  609. X            }
  610. X            written = (int)ftell(fp);
  611. X            fprintf(stderr,"(continue)\n");
  612. X            continue;
  613. X        }    
  614. X        else if (io[0] == '~' && io[1] == 'p' && tty)
  615. X        {
  616. X            rewind(fp);
  617. X            fprintf(stderr,"-------\nMessage contains:\n");
  618. X            while (fgets(io, 248, fp) != NULL)
  619. X                fputs(io, stderr);
  620. X            fprintf(stderr,"(continue)\n");
  621. X            fseek(fp, 0L, 2);
  622. X            continue;
  623. X        }
  624. X        written += strlen(io);
  625. X        fputs(io, fp);
  626. X    }
  627. X    fclose(fp);
  628. X    if (broken || !written)
  629. X    {
  630. X        unlink(tmpname);
  631. X        fprintf(stderr,"null message, not sent\n");
  632. X        return(NULL);
  633. X    }
  634. X    if ((fp = fopen(tmpname, "r")) == NULL)
  635. X    {
  636. X        fprintf(stderr,"can't re-read your tmp file\n");
  637. X        return(NULL);
  638. X    }
  639. X    return(fp);
  640. X}
  641. Xsavefax(infile)
  642. Xchar *infile;
  643. X{
  644. X    time_t ca;
  645. X    struct tm *tml, *localtime();
  646. X    struct stat fred;
  647. X    char FaxSent[256];
  648. X    FILE *in, *sfp;
  649. X
  650. X    time(&ca);
  651. X    tml = localtime(&ca);
  652. X    ++tml->tm_mon;        /* jan is often 0 */
  653. X    
  654. X    if (*home == '/' && *(home+1) == '\0')
  655. X    {
  656. X        strcpy(FaxSent, "/FaxSent");
  657. X        sprintf(io,"/FaxSent/%s.%02d%02d%02d",
  658. X            phone[0],tml->tm_year,tml->tm_mon,tml->tm_mday);
  659. X    }
  660. X    else
  661. X    {
  662. X        sprintf(FaxSent,"%s/FaxSent",home);
  663. X        sprintf(io,"%s/FaxSent/%s.%02d%02d%02d",home,
  664. X            phone[0],tml->tm_year,tml->tm_mon,tml->tm_mday);
  665. X    }
  666. X
  667. X    if (stat(FaxSent, &fred) && mkdir(FaxSent, 0700))
  668. X    {
  669. X        fprintf(stderr,"no directory %s\n",FaxSent);
  670. X        exit(1);
  671. X    }
  672. X    if (((sfp = fopen(io, "a")) == NULL)
  673. X        || ((in = fopen(infile, "r")) == NULL))
  674. X    {
  675. X        fprintf(stderr,"can't save your fax to %s in %s\n",
  676. X            phone[0],io);
  677. X        exit(1);
  678. X    }
  679. X    fprintf(sfp,"\n\nSPOOLED %02d.%02d.%2d %02d:%02d:%02d\n",
  680. X        tml->tm_mday,tml->tm_mon,tml->tm_year,
  681. X        tml->tm_hour,tml->tm_min,tml->tm_sec);
  682. X
  683. X    while (fgets(io, 250, in) != NULL)
  684. X        fputs(io, sfp);
  685. X    fclose(in);
  686. X    fclose(sfp);
  687. X}
  688. Xedit(what)
  689. Xchar *what;
  690. X{
  691. X    char *ed;
  692. X
  693. X    if ((ed = getenv("EDITOR")) == NULL)
  694. X        ed = "/usr/ucb/vi";
  695. X
  696. X    sprintf(io, "%s %s\n",ed,what);
  697. X    system(io);
  698. X}
  699. Xusage()
  700. X{
  701. X    char tmp[40];
  702. X
  703. X    puts("fax options:");
  704. X    puts("-a\"for the attention of fred bloggs\"");
  705. X    puts("-h   use high resolution");
  706. X    puts("-f   use an hp ljet  compatible font");
  707. X    puts("-n   send it now");
  708. X    puts("-m   confirm result by mail when sent");
  709. X    puts("-r   specify return fax no");
  710. X    if (*home == '/' && *(home+1) == '\0')
  711. X        strcpy(tmp, "/FaxSent");
  712. X    else sprintf(tmp,"%s/FaxSent",home);
  713. X    printf("-s   save message in %s/phoneno.date\n",tmp);
  714. X    puts("if called without a file name, fax reads stdin");
  715. X    exit(1);
  716. X}
  717. END_OF_FILE
  718.   if test 14931 -ne `wc -c <'faxclient/fax.c'`; then
  719.     echo shar: \"'faxclient/fax.c'\" unpacked with wrong size!
  720.   fi
  721.   # end of 'faxclient/fax.c'
  722. fi
  723. if test -f 'faxhost/spool.fax.c' -a "${1}" != "-c" ; then 
  724.   echo shar: Will not clobber existing file \"'faxhost/spool.fax.c'\"
  725. else
  726.   echo shar: Extracting \"'faxhost/spool.fax.c'\" \(14959 characters\)
  727.   sed "s/^X//" >'faxhost/spool.fax.c' <<'END_OF_FILE'
  728. X#include <stdio.h>
  729. X#include <string.h>
  730. X#include <time.h>
  731. X#include <ctype.h>
  732. X#include <unistd.h>
  733. X
  734. X#include "../faxconfig.h"
  735. X
  736. X/*
  737. X    spool.fax
  738. X
  739. X    spool faxes,
  740. X    read incoming jobs,
  741. X    split into straight through jobs and jobs where that
  742. X        need special handling due to "f.t.a.o. fred bloggs"
  743. X    convert input -> pbm -> g3
  744. X    if straight through jobs > 1 && phone_nos > 1,
  745. X        split into batches of size (phone_nos/faxmodems)
  746. X
  747. X    this looks [and is] rather messy due to the last minute addition
  748. X    of special treatment of those guys that doen't have their own
  749. X    fax machine but want their fax addressed [marked] "for the
  750. X    attention of whatever". The quick fix I made works, but
  751. X    the resulting mess is barely understandable [to me, that is].
  752. X
  753. X    I'm gonna rework him as soon as there's some time - I probably
  754. X    have to anyway when I add prettier file types. Currently
  755. X    the only thing that works as advertised is files pushed through
  756. X    texttopbm. spooling faxes with pbm files should work, but I haven't
  757. X    had the time to test these [hey, I'm doing this in my spare time].
  758. X
  759. X    first released version 0.99 [desperado version]
  760. X    cleaned up Jan 22nd '91, 
  761. X    Copyright (C) 1991, klaus schallhorn, klaus@cnix.uucp
  762. X
  763. X    Permission to use, copy, modify, and distribute this software 
  764. X    and its documentation for any purpose and without fee is hereby 
  765. X    granted, provided that the above copyright notice appear in 
  766. X    all copies and that both that copyright notice and this permission 
  767. X    notice appear in supporting documentation. 
  768. X
  769. X    This software is provided "as is" without express or implied warranty.
  770. X*/
  771. X
  772. X
  773. Xlong    xpos;
  774. Xint    type, hires, pages, blah, mail;
  775. Xchar    tmp_nam[256], user[80], retfax[80], font[256], Ftao[256];
  776. Xchar    io[1024], Xfile[256], Dfile[256];
  777. Xchar    oldname[256], newname[256], linkbase[256], linkto[256], dataname[256];
  778. X#ifdef    JOBID
  779. X    jobid[80];
  780. Xstruct    tm *tml, *localtime();
  781. X#endif
  782. X
  783. Xextern    int errno;
  784. X
  785. Xchk_config()
  786. X{
  787. X    FILE *cfg;
  788. X    char buf[256];
  789. X    int i;
  790. X
  791. X    sprintf(buf, "%s/fax.config", FAXLIB);
  792. X    errno = 0;
  793. X    if ((cfg = fopen(buf, "r")) == NULL)
  794. X    {
  795. X        unlink(Xfile);
  796. X        unlink(Dfile);
  797. X        fax_log(ERROR, "spool.fax: can't read %s\n",buf);
  798. X        mailexit(user);
  799. X    }
  800. X    i = 0;
  801. X    while (fgets(buf, 254, cfg) != NULL)
  802. X    {
  803. X        if (buf[0] == '#')
  804. X            continue;
  805. X        if (!strncmp(buf, "device", 6))
  806. X            ++i;
  807. X    }
  808. X    fclose(cfg);
  809. X    return(i);
  810. X}
  811. X
  812. Xmain()
  813. X{
  814. X    FILE *fp;
  815. X    int nread, phones, tread, count, ftaofs;
  816. X    time_t now;
  817. X    char *ptr;
  818. X
  819. X    phones = count = ftaofs = tread = errno = 0;
  820. X    user[0] = retfax[0] = font[0] = Ftao[0] = '\0';
  821. X
  822. X    if (chdir(FAXSPOOL))    /* quick one, job done */
  823. X    {
  824. X        fax_log(ERROR,"spool.fax: can't cd to %s\n",FAXSPOOL);
  825. X        mailexit(FAXADMIN);
  826. X    }
  827. X
  828. X    (void)time(&now);
  829. X
  830. X#ifdef    JOBID
  831. X    tml = localtime(&now);
  832. X    ++tml->tm_mon;        /* jan is 0 */
  833. X
  834. X    sprintf(jobid, "%02d%02d-%d",tml->tm_mon,tml->tm_mday,getpid());
  835. X#endif
  836. X    sprintf(tmp_nam,"%s/X.faxXXXXXX",FAXSPOOL);
  837. X    mktemp(tmp_nam);
  838. X    strcpy(Xfile, tmp_nam);
  839. X
  840. X    if ((fp = fopen(tmp_nam, "w")) == NULL)
  841. X    {
  842. X        fax_log(ERROR,"spool.fax: can't create X.file\n");
  843. X        mailexit(FAXADMIN);
  844. X    }
  845. X        
  846. X    chmod(tmp_nam, FAXFMODE);
  847. X
  848. X    fprintf(fp,"spooled %ld\n",(long)now);
  849. X    fprintf(fp,"tries %3d\n",0);
  850. X
  851. X    while (fgets(io, 254, stdin) != NULL)
  852. X    {
  853. X        if (!count)
  854. X        {
  855. X            if (io[0] == 'f')    /* font */
  856. X            {
  857. X                ptr = io;
  858. X                while (*ptr && (!isspace(*ptr)))
  859. X                    ++ptr;
  860. X                ++ptr;
  861. X                if (strncmp(ptr, "none", 4))
  862. X                    strcpy(font, ptr);    /* else use default */
  863. X            }
  864. X            else if (io[0] == 'h')    /* hires */
  865. X            {
  866. X                ptr = io;
  867. X                while (*ptr && (!isdigit(*ptr)))
  868. X                    ++ptr;
  869. X                hires = atoi(ptr);
  870. X            }
  871. X            else if (io[0] == 'm')    /* hires */
  872. X            {
  873. X                ptr = io;
  874. X                while (*ptr && (!isdigit(*ptr)))
  875. X                    ++ptr;
  876. X                mail = atoi(ptr);
  877. X            }
  878. X            else if (io[0] == 'r')    /* return faxno */
  879. X            {
  880. X                ptr = io;
  881. X                while (*ptr && (!isspace(*ptr)))
  882. X                    ++ptr;
  883. X                strcpy(retfax, ++ptr);
  884. X            }
  885. X            else if (io[0] == 't')    /* type */
  886. X            {
  887. X                ptr = io;
  888. X                while (*ptr && (!isdigit(*ptr)))
  889. X                    ++ptr;
  890. X                type = atoi(ptr);
  891. X            }
  892. X            else if (io[0] == 'u' && (!user[0]))    /* user */
  893. X            {
  894. X                ptr = io;
  895. X                while (*ptr && (!isspace(*ptr)))
  896. X                    ++ptr;
  897. X                strcpy(user, ++ptr);
  898. X            }
  899. X            else if (io[0] == '#')
  900. X            {
  901. X                xpos = ftell(fp);
  902. X                count = TRUE;
  903. X            }
  904. X        }
  905. X        else
  906. X        {
  907. X            if (io[0] == 'd')    /* data follows */
  908. X                break;
  909. X            else if (io[0] == 'p')    /* last minute fix */
  910. X            {            /* forgot ftao for 1off faxes */
  911. X                ++phones;    /* added to faxconvert */
  912. X                if ((ptr = strchr(io, ':')) != NULL)
  913. X                {
  914. X                    ftaofs++;
  915. X                    strcpy(Ftao, (ptr+1));
  916. X                }
  917. X            }
  918. X        }
  919. X        fputs(io, fp);
  920. X    }
  921. X    sprintf(tmp_nam,"%s/D.faxXXXXXX",FAXSPOOL);
  922. X    mktemp(tmp_nam);
  923. X    strcpy(Dfile, tmp_nam);
  924. X
  925. X        /* make a note of D.file name in X.file */
  926. X    fprintf(fp,"data %s\n",tmp_nam);
  927. X    fflush(fp);
  928. X    if (ferror(fp))
  929. X    {
  930. X        unlink(Xfile);
  931. X        fax_log(ERROR,"spool.fax: can't write X.file\n");
  932. X        mailexit(FAXADMIN);
  933. X    }
  934. X    fclose(fp);
  935. X
  936. X    if ((!user[0]) || (!phones))
  937. X    {
  938. X        unlink(Xfile);
  939. X        fax_log(ERROR,"spool.fax: doesn't look like a fax job to me\n");
  940. X        mailexit(FAXADMIN);
  941. X    }
  942. X
  943. X    if ((fp = fopen(tmp_nam, "w")) == NULL)
  944. X    {
  945. X        unlink(Xfile);
  946. X        fax_log(ERROR,"spool.fax: can't create D.file\n");
  947. X        mailexit(user);
  948. X    }
  949. X    chmod(tmp_nam, FAXFMODE);
  950. X
  951. X    while ((nread = fread(io, 1, 256, stdin)) > 0)
  952. X    {
  953. X        tread += nread;
  954. X        if (fwrite(io, 1, nread, fp) != nread)
  955. X        {
  956. X            unlink(Xfile);
  957. X            fax_log(ERROR,"spool.fax: can't write D.file\n");
  958. X            mailexit(user);
  959. X        }
  960. X    }
  961. X    fflush(fp);
  962. X    if ((!tread) || ferror(fp))    /* empty file ? */
  963. X    {
  964. X        unlink(Xfile);
  965. X        unlink(Dfile);
  966. X        fax_log(ERROR,"spool.fax: can't write D.file, rcvd bytes %d\n",tread);
  967. X        mailexit(user);
  968. X    }
  969. X    fclose(fp);
  970. X
  971. X    if ((nread = fork()) < 0)
  972. X    {
  973. X        unlink(Xfile);
  974. X        unlink(Dfile);
  975. X        fax_log(ERROR,"spool.fax: can't fork to convert files\n");
  976. X        mailexit(user);
  977. X    }
  978. X    else if (!nread)    /* child */
  979. X    {
  980. X        if (setpgrp(0,0))
  981. X        {
  982. X            fax_log(ERROR, "spool.fax: can't create new prgp\n");
  983. X            mailexit(FAXADMIN);
  984. X        }
  985. X        if (setuid(geteuid()))
  986. X        {
  987. X            fax_log(ERROR, "spool.fax: can't setuid(geteuid())\n");
  988. X            mailexit(FAXADMIN);
  989. X        }
  990. X        if (setgid(getegid()))
  991. X        {
  992. X            fax_log(ERROR, "spool.fax: can't setgid(getegid())\n");
  993. X            mailexit(FAXADMIN);
  994. X        }
  995. X
  996. X        if (!share_fax(Xfile,Dfile,phones,ftaofs))
  997. X#ifndef    JOBID
  998. X            fax_log(0, "spool.fax: user %s, %d pages, %d reciepient%c\n",
  999. X                user, pages, phones, (phones > 1)?'s':' ');
  1000. X#else
  1001. X            fax_log(0, "spool.fax: jobid %s, user %s, %d pages, %d reciepient%c\n",
  1002. X                jobid, user, pages, phones, (phones > 1)?'s':' ');
  1003. X
  1004. X        if (mail)
  1005. X        {
  1006. X            sprintf(io,"echo \"the job id of your spooled fax is %s \" | mail %s",
  1007. X                jobid,user);
  1008. X            system(io);
  1009. X        }
  1010. X#endif
  1011. X
  1012. X    }
  1013. X    exit(0);
  1014. X}
  1015. Xshare_fax(xnam,dnam,phones,oneoffs)
  1016. Xchar *xnam,*dnam;
  1017. Xint phones, oneoffs;
  1018. X{
  1019. X    FILE *X, *x;
  1020. X    char name[256], io[1024], *head;
  1021. X    int i, split, batches, done, per_batch, devices;
  1022. X
  1023. X    /* split a job into packets 
  1024. X       check for jobs with special headers [ftao], do separately,
  1025. X       split the balance into packets so that load is distributed
  1026. X       evenly between faxmodems
  1027. X    */
  1028. X
  1029. X    devices = chk_config();    /* or dead */
  1030. X
  1031. X    if (phones == 1)    /* doesn't need much splitting */
  1032. X        return(faxconvert(xnam,dnam,0));
  1033. X    else Ftao[0] = '\0';    /* last minute fix, spoolfax is due for a rewrite */
  1034. X
  1035. X    if (oneoffs)        /* special handling */
  1036. X        phones -= xoneoffs(xnam,dnam);
  1037. X
  1038. X            /* integer divide of 7 faxes / 10 modems == 0 */
  1039. X    per_batch = max(1,(phones/devices));
  1040. X    errno = 0;
  1041. X    if ((X = fopen(xnam, "r")) == NULL)
  1042. X    {
  1043. X        fax_log(ERROR,"spool.fax: can't open X.file %s\n",xnam);
  1044. X        mailexit(user);
  1045. X    }
  1046. X    if ((head = malloc((int)xpos)) == NULL)
  1047. X    {
  1048. X        fax_log(ERROR,"spool.fax: can't allocate memory\n");
  1049. X        mailexit(user);
  1050. X    }
  1051. X    if (fread(head, 1, (int)xpos, X) != (int)xpos)
  1052. X    {
  1053. X        fax_log(ERROR,"spool.fax: can't read X.file %s\n",xnam);
  1054. X        mailexit(user);
  1055. X    }
  1056. X
  1057. X    for (done=batches=split=0;;)
  1058. X    {
  1059. X        if (done || (split == phones))
  1060. X            break;
  1061. X
  1062. X        sprintf(name, "%s%d",xnam,batches);
  1063. X        if ((x = fopen(name, "w")) == NULL)    /* buggered */
  1064. X        {                    /* rm all batches */
  1065. Xbuggered:
  1066. X            for (i=0; i<batches; i++)        /* but leave main job */
  1067. X            {                /* for manual cleanup */
  1068. X                sprintf(name, "%s%d",xnam,i);
  1069. X                unlink(name);
  1070. X            }
  1071. X            unlink(xnam);
  1072. X            unlink(dnam);
  1073. X            fax_log(ERROR,"spool.fax: serious problems during split %s\n",xnam);
  1074. X            mailexit(user);
  1075. X        }
  1076. X
  1077. X        chmod(name, FAXFMODE);
  1078. X        if (fwrite(head, 1, (int)xpos, x) != (int)xpos)
  1079. X            goto buggered;
  1080. X
  1081. X        for (i=0; i<per_batch; )
  1082. X        {
  1083. X            if (fgets(io, 256, X) == NULL)
  1084. X                goto buggered;
  1085. X            if (io[0] == '#' || (strchr(io, ':') != NULL))
  1086. X                continue;
  1087. X            if (!strncmp(io, "data", 4)) /* no more phone nos */
  1088. X            {
  1089. X                if (!i)
  1090. X                    unlink(name);
  1091. X                done = 1;
  1092. X                break;
  1093. X            }
  1094. X            fputs(io, x);
  1095. X            ++split;
  1096. X            ++i;
  1097. X        }
  1098. X        fprintf(x,"data %s\n",dnam);
  1099. X        fflush(x);
  1100. X        if (ferror(x))
  1101. X            goto buggered;
  1102. X        fclose(x);
  1103. X        batches += (i > 0);
  1104. X    }
  1105. X    fclose(X);
  1106. X    unlink(xnam);    /* passed on simply as a "basename" */
  1107. X    return(faxconvert(xnam,dnam,batches));
  1108. X}
  1109. Xxoneoffs(xnam,dnam)
  1110. Xchar *xnam,*dnam;
  1111. X{
  1112. X    FILE *X, *D, *x, *d;
  1113. X    char ftao[128], newxnam[256], newdnam[256], txnam[256], tdnam[256],
  1114. X        *head, *ptr;
  1115. X    int split, nread;
  1116. X
  1117. X    errno = 0;
  1118. X    if ((D = fopen(dnam, "r")) == NULL)
  1119. X    {
  1120. X        fax_log(ERROR,"spool.fax: can't open D.file %s for ftao\n",dnam);
  1121. X        mailexit(user);
  1122. X    }
  1123. X    if ((X = fopen(xnam, "r")) == NULL)
  1124. X    {
  1125. X        fax_log(ERROR,"spool.fax: can't open X.file %s for ftao\n",xnam);
  1126. X        mailexit(user);
  1127. X    }
  1128. X        /* read header of X file */
  1129. X    if ((head = malloc((int)xpos)) == NULL)
  1130. X    {
  1131. X        fax_log(ERROR,"spool.fax: can't allocate memory\n");
  1132. X        mailexit(user);
  1133. X    }
  1134. X    if (fread(head, 1, (int)xpos, X) != (int)xpos)
  1135. X    {
  1136. X        fax_log(ERROR,"spool.fax: can't read X.file %s for ftao\n",xnam);
  1137. X        mailexit(user);
  1138. X    }
  1139. X
  1140. X    split = 0;    /* find jobs with phone 1234 :f.t.a.o fred */
  1141. X    sprintf(txnam,"%s/X.fxXXXXXX",FAXSPOOL);
  1142. X    mktemp(txnam);
  1143. X    sprintf(tdnam,"%s/D.fxXXXXXX",FAXSPOOL);
  1144. X    mktemp(tdnam);
  1145. X
  1146. X    while (fgets(io, 256, X) != NULL)
  1147. X    {
  1148. X        if (io[0] == '#' || ((ptr = strchr(io, ':')) == NULL))
  1149. X            continue;
  1150. X
  1151. X        sprintf(newxnam, "%s%d", txnam,split);
  1152. X        errno = 0;
  1153. Xbuggered:
  1154. X        if ((x = fopen(newxnam, "w")) == NULL)
  1155. X        {
  1156. X            fax_log(ERROR,"spool.fax: can't create %s for load sharing\n",newxnam);
  1157. X            mailexit(user);
  1158. X        }
  1159. X        chmod(newxnam, FAXFMODE);
  1160. X
  1161. X        if (fwrite(head, 1, (int)xpos, x) != (int)xpos)
  1162. X            goto buggered;
  1163. X
  1164. X        strcpy(ftao, (ptr+1));    /* save whats after ptr */
  1165. X        *ptr = '\0';        /* zero out at ':' */
  1166. X
  1167. X        /* io now contains just the phone number */
  1168. X        /* ftao contains now "f.t.a.o. fred" */
  1169. X
  1170. X        /* make new data name */
  1171. X        sprintf(newdnam,"%s%d", tdnam,split);
  1172. X
  1173. X        fprintf(x,"%s\ndata %s\n",io,newdnam);
  1174. X        fflush(x);
  1175. X        if (ferror(x))
  1176. X            goto buggered;
  1177. X        fclose(x);
  1178. X
  1179. X        errno = 0;
  1180. X        if ((d = fopen(newdnam, "w")) == NULL)
  1181. X            goto buggered;
  1182. X        chmod(newdnam, FAXFMODE);
  1183. X
  1184. X        fprintf(d,"%s\n",ftao);    /* make this part of the fax file */
  1185. X
  1186. X                    /* add the balance */
  1187. X        while ((nread = fread(io, 1, 1024, D)) > 0)
  1188. X            fwrite(io, 1, nread, d);
  1189. X        fflush(d);
  1190. X        if (ferror(d))
  1191. X            goto buggered;
  1192. X        fclose(d);
  1193. X        faxconvert(newxnam, newdnam, 0);    /* or die */
  1194. X        ++split;
  1195. X        rewind(D);
  1196. X    }
  1197. X    fclose(X);
  1198. X    fclose(D);
  1199. X    free(head);
  1200. X    return(split);
  1201. X}
  1202. Xfaxconvert(xn, dn, batches)
  1203. Xchar *xn, *dn;
  1204. Xint batches;
  1205. X{
  1206. X    int j, batch;
  1207. X    char scratchbuf[256], tmp[256], *ptr;
  1208. X    FILE *p, *fp;
  1209. X
  1210. X    /* do D.files [data] first, if they're ok, do Xfiles */
  1211. X    /* sendfax scans directory for x.files only */
  1212. X    /* in case of multiple batches convert data once, then make links */
  1213. X
  1214. X    batch = 0;
  1215. X    do    /* at least once */
  1216. X    {
  1217. X        if (!batch)    /* first time around */
  1218. X        {
  1219. X            strcpy(oldname, dn);
  1220. X            strcpy(newname, dn);
  1221. X            ptr = strrchr(newname, '/');
  1222. X            *(ptr+1) = 'd';
  1223. X            strcpy(linkto, newname);
  1224. X            strcat(newname, "0");
  1225. X            strcpy(linkbase, newname);
  1226. X
  1227. X                /* strip newlines */
  1228. X            if ((ptr = strchr(font, '\n')) != NULL)
  1229. X                *ptr = '\0';
  1230. X            if ((ptr = strchr(user, '\n')) != NULL)
  1231. X                *ptr = '\0';
  1232. X            if ((ptr = strchr(retfax, '\n')) != NULL)
  1233. X                *ptr = '\0';
  1234. X
  1235. X            switch(type)
  1236. X            {
  1237. X            case ASCII:
  1238. X                errno = 0;
  1239. X                if ((fp = fopen(oldname, "r")) == NULL)
  1240. X                {
  1241. X                    fax_log(ERROR,"spool.fax: can't read textfile %s for conversion\n",oldname);
  1242. X                    mailexit(user);
  1243. X                }
  1244. X                sprintf(scratchbuf,"%s/texttopbm %s %s%s -o%s.pbm",
  1245. X                    LOCALBIN,
  1246. X                    (hires)?"-h":"",
  1247. X                    (font[0])?"-f":"",
  1248. X                    (font[0])?font:"",
  1249. X                    newname);
  1250. X
  1251. X                if ((p = popen(scratchbuf, "w")) == NULL)
  1252. X                {
  1253. X                    fax_log(ERROR,"spool.fax: can't pipe to texttopbm with %s\n",scratchbuf);
  1254. X                    mailexit(user);
  1255. X                }
  1256. X
  1257. X                if (Ftao[0]) /* make this part of the fax file */
  1258. X                    fprintf(p,"%s\n",Ftao);
  1259. X                fprintf(p,"fax from %s",user);
  1260. X                if (strncmp(retfax, "none", 4))
  1261. X                    fprintf(p,", fax # %s - ",retfax);
  1262. X                else fputc(' ',p);
  1263. X                timestamp(p,(time_t)0L);
  1264. X
  1265. X                fprintf(p,"\n\n");
  1266. X
  1267. X                while (fgets(scratchbuf, 254, fp) != NULL)
  1268. X                    fputs(scratchbuf, p);
  1269. X
  1270. X                fflush(p);
  1271. X                if (ferror(p))
  1272. X                {
  1273. X                    fax_log(ERROR,"spool.fax: can't unplump from texttopbm with %s\n",scratchbuf);
  1274. X                    mailexit(user);
  1275. X                }
  1276. X                pclose(p);
  1277. X                fclose(fp);
  1278. X                unlink(oldname);    /* rm text input file */
  1279. X
  1280. X                    /* have one or more pbm files now */
  1281. X                for (pages=0;;pages++)
  1282. X                {
  1283. X                    sprintf(tmp, "%s.pbm.%d",newname,pages);
  1284. X                    if (access(tmp, R_OK))
  1285. X                        break;
  1286. X                    sprintf(scratchbuf,"%s/pbmtog3 -s <%s >%s.g3.%d",LOCALBIN,tmp,newname,pages);
  1287. X                    if (system(scratchbuf))
  1288. X                    {
  1289. X                        fax_log(ERROR,"spool.fax: can't execute pbmtog3 with %s\n",scratchbuf);
  1290. X                        mailexit(user);
  1291. X                    }
  1292. X                    unlink(tmp);    /* get rid of pbm file */
  1293. X                    sprintf(tmp, "%s.g3.%d",newname,pages);
  1294. X                    chmod(tmp, FAXFMODE);
  1295. X                }
  1296. X                strcpy(dataname, linkbase);
  1297. X                break;
  1298. X
  1299. X            case PBM:
  1300. X                sprintf(scratchbuf,"pbmtog3 -s <%s >%s.g3.0",oldname,newname);
  1301. X                errno = 0;
  1302. X                if (system(scratchbuf))
  1303. X                {
  1304. X                    fax_log(ERROR,"spool.fax: can't execute pbmtog3 with %s\n",scratchbuf);
  1305. X                    mailexit(user);
  1306. X                }
  1307. X                unlink(oldname);    /* again: get rid of pbm file */
  1308. X                sprintf(tmp,"%s.g3.0",newname);
  1309. X                chmod(tmp, FAXFMODE);
  1310. X                pages = 1;
  1311. X                strcpy(dataname, newname);
  1312. X                break;
  1313. X            }
  1314. X        }
  1315. X        else
  1316. X        {
  1317. X            for (j=0; j<pages; j++)
  1318. X            {
  1319. X                sprintf(dataname,   "%s%d.g3.%d",linkto,batch,j);
  1320. X                sprintf(scratchbuf, "%s.g3.%d",linkbase,j);
  1321. X                if (link(scratchbuf, dataname))
  1322. X                {
  1323. X                    fax_log(ERROR,"spool.fax: can't link %s to %s\n",linkbase,tmp);
  1324. X                    mailexit(user);
  1325. X                }
  1326. X            }
  1327. X            sprintf(dataname, "%s%d",linkto,batch);
  1328. X        }
  1329. X
  1330. X
  1331. X                /* now do the X.file */
  1332. X        if (batches)    /* xn is basename only in case of batches */
  1333. X            sprintf(oldname, "%s%d", xn, batch);
  1334. X        else strcpy(oldname, xn);
  1335. X
  1336. X        strcpy(newname, oldname);
  1337. X        ptr = strrchr(newname, '/');
  1338. X        *(ptr+1) = 'x';
  1339. X        if ((p = fopen(oldname, "r")) == NULL)
  1340. X        {
  1341. X            fax_log(ERROR,"spool.fax: can't open %s after splitting D.files\n",oldname);
  1342. X            mailexit(user);
  1343. X        }
  1344. X        if ((fp = fopen(newname, "w")) == NULL)
  1345. X        {
  1346. X            fax_log(ERROR,"spool.fax: can't create new %s\n",newname);
  1347. X            mailexit(user);
  1348. X        }
  1349. X        chmod(newname, FAXFMODE);
  1350. X
  1351. X        while (fgets(scratchbuf, 126, p) != NULL)
  1352. X        {
  1353. X            if (!strncmp(scratchbuf, "data", 4))
  1354. X                fprintf(fp,"data %s\n",dataname);
  1355. X            else fputs(scratchbuf, fp);
  1356. X        }
  1357. X        fprintf(fp,"pages %d\n",pages);
  1358. X#ifdef    JOBID
  1359. X        fprintf(fp,"jobid %s\n",jobid);
  1360. X#endif
  1361. X        fflush(fp);
  1362. X        if (ferror(fp))
  1363. X        {
  1364. X            fax_log(ERROR,"spool.fax: can't write new %s\n",newname);
  1365. X            mailexit(user);
  1366. X        }
  1367. X        fclose(fp);
  1368. X        unlink(oldname);
  1369. X    } while (++batch < batches);
  1370. X
  1371. X    unlink(dn);
  1372. X    return(0);
  1373. X}
  1374. END_OF_FILE
  1375.   if test 14959 -ne `wc -c <'faxhost/spool.fax.c'`; then
  1376.     echo shar: \"'faxhost/spool.fax.c'\" unpacked with wrong size!
  1377.   fi
  1378.   # end of 'faxhost/spool.fax.c'
  1379. fi
  1380. if test -f 'sample.fax.aliases' -a "${1}" != "-c" ; then 
  1381.   echo shar: Will not clobber existing file \"'sample.fax.aliases'\"
  1382. else
  1383.   echo shar: Extracting \"'sample.fax.aliases'\" \(290 characters\)
  1384.   sed "s/^X//" >'sample.fax.aliases' <<'END_OF_FILE'
  1385. X# sample fax.aliases file
  1386. X# alias   phone no   ftao, starts with a colon         optional comment
  1387. X#---------------------------------------------------------------------
  1388. Xfred    12345678   :for the attention of fred bloggs # comment
  1389. Xbill    98765
  1390. Xjoe    7654323       :The Lady in Pink # should see her
  1391. END_OF_FILE
  1392.   if test 290 -ne `wc -c <'sample.fax.aliases'`; then
  1393.     echo shar: \"'sample.fax.aliases'\" unpacked with wrong size!
  1394.   fi
  1395.   # end of 'sample.fax.aliases'
  1396. fi
  1397. if test -f 'writefax.man' -a "${1}" != "-c" ; then 
  1398.   echo shar: Will not clobber existing file \"'writefax.man'\"
  1399. else
  1400.   echo shar: Extracting \"'writefax.man'\" \(20046 characters\)
  1401.   sed "s/^X//" >'writefax.man' <<'END_OF_FILE'
  1402. X>From cat!fulcrum!ukc.ac.uk!mcsun.eu.net!mcsun.uucp!aimed!nick Thu Dec 13 15:41:13 1990
  1403. XReturn-Path: <cat!fulcrum!ukc.ac.uk!mcsun.eu.net!mcsun.uucp!aimed!nick>
  1404. XSubject: Re: writefax.man
  1405. XTo: klaus u schallhorn <klaus@cnix.uucp>
  1406. XDate: Wed, 12 Dec 90 16:49:33 EST
  1407. X>From: Nick Pemberton <aimed!nick>
  1408. XX-Mailer: ELM [version 2.3 PL6]
  1409. XSender: uucp.mcsun!aimed!nick@mcsun.eu.net
  1410. X    
  1411. X> I've just studied the document you posted to various newsgroups
  1412. X> and compared it to a document I received from a faxmodem
  1413. X> manufacturer, that asked me to sign a non disclosure agreement
  1414. X> in order to get what you posted.      ************************
  1415. X    
  1416. XThat sounds reasonably scary....
  1417. X    
  1418. X> 
  1419. X> Can you let me know the source of the document and if it's
  1420. X> "secret" as well or whether I've been done. I'd really like to know.
  1421. X
  1422. XI downloaded it from the Zoom Technologies BBS, at 1-617-451-5284. Zoom
  1423. Xare the folks who manufacture the modem - the chipset must be Sierra's.
  1424. X
  1425. XAs you can see from the document, there are no restrictive covenants
  1426. Xon it, and zoom never mentioned such restrictions. I'd question having to
  1427. Xsign such an agreement.
  1428. X
  1429. XNick.
  1430. X
  1431. X-- 
  1432. XNick Pemberton           uucp: !{lsuc, uunet!mnetor}!aimed!nick
  1433. XAIM, Inc              bus: (416) 429-1085
  1434. XToronto, Ontario, Canada         Home: (416) 690-0647
  1435. X
  1436. X
  1437. X>From cat.fulcrum.bt.co.uk!uzi-9mm.fulcrum.bt.co.uk!axion!ukc!mcsun!sunic!uupsi!rpi!zaphod.mps.ohio-state.edu!wuarchive!cs.utexas.edu!utgpu!utzoo!mnetor!geac!aimed!nick Wed Dec 12 10:38:53 GMT 1990
  1438. XArticle: 112 of comp.dcom.modems
  1439. XXref: cnix alt.fax:79 comp.dcom.modems:112 comp.periphs:92
  1440. XPath: cnix!cat.fulcrum.bt.co.uk!uzi-9mm.fulcrum.bt.co.uk!axion!ukc!mcsun!sunic!uupsi!rpi!zaphod.mps.ohio-state.edu!wuarchive!cs.utexas.edu!utgpu!utzoo!mnetor!geac!aimed!nick
  1441. X>From: nick@aimed.UUCP (Nick Pemberton)
  1442. XNewsgroups: alt.fax,comp.dcom.modems,comp.periphs
  1443. XSubject: Here is WRITEFAX.MAN, details on ZOOM modem programming
  1444. XMessage-ID: <8658@aimed.UUCP>
  1445. XDate: 8 Dec 90 00:30:56 GMT
  1446. XOrganization: AIM, Inc, Toronto, Ontario
  1447. XLines: 496
  1448. X
  1449. XWell, after much waiting, dialing, etc, I finally have a copy of
  1450. XWRITEFAX.MAN, which is a guide to programming the ZOOM MX 2400S modem,
  1451. Xamongst others. I have had a number of requests for this file, so I
  1452. Xthought I'd post it (its not that large anyway....)
  1453. X
  1454. X------------snip----------snip--------snip---------
  1455. X      SendFax Application Software Interface Specification Rev 2
  1456. X
  1457. X
  1458. X
  1459. XContents
  1460. X
  1461. X1.0    Introduction
  1462. X
  1463. X2.0    Physical interface
  1464. X
  1465. X3.0    Command set
  1466. X
  1467. X4.0    Data format
  1468. X
  1469. X5.0    Example sessions
  1470. X
  1471. X
  1472. X
  1473. X
  1474. X.pa
  1475. X.he       SendFax Application Software Interface Specification
  1476. X
  1477. X
  1478. X
  1479. X1.0    Introduction
  1480. X
  1481. XThis  document  defines the specifications  for  the  application 
  1482. Xsoftware interface to a PC Fax/Modem board incorporating Sierra's 
  1483. XSC11046, 2400 bps modem with Send only Fax at 4800 bps  (SendFax) 
  1484. Xchip.
  1485. X
  1486. XThe  device is intended to be used in internal cards for the  IBM 
  1487. XPC  or  compatible  computers or for  use  in  standalone  modems 
  1488. Xinterfacing to   any  computer using a standard RS232 port. 
  1489. X
  1490. XFunctions  and commands are defined to allow an extension to  Fax 
  1491. Xreceive mode in the future.
  1492. XThe Fax/Modem board is designed such that it appears to the PC as 
  1493. Xa serial port.  The address of the board is user selectable to be 
  1494. Xone  of four ports, COM1, COM2, COM3 or COM4.  The  DCE  hardware 
  1495. Xmakes  and terminates calls, manages the  communications  session 
  1496. Xand  transmits  image  data in  accordance  with  the  procedures 
  1497. Xdefined  in the CCITT recommendation T.30.  The image data is  in 
  1498. Xmodified  Huffman  compressed format as described  in  the  CCITT 
  1499. Xrecommendation T.4.  
  1500. X
  1501. XThe  application  software running in the DTE  will  provide  the 
  1502. Xfunctions  of  user interface, conversion of user data  files  in 
  1503. Xvarious  formats  to fax format per CCITT T.4  specification  and 
  1504. Xtransfer  of  data  to the DCE for modulation  according  to  the 
  1505. Xprotocol defined in this document.
  1506. X
  1507. X.pa
  1508. X
  1509. X
  1510. X
  1511. X2.0    Physical Interface
  1512. X
  1513. X2.1 Internal PC version
  1514. X
  1515. XThe  hardware  appears to the PC as a serial port at  an  address 
  1516. Xthat  is user selectable to be one of four ports.  Table 1  lists 
  1517. Xthe addresses and interrupt levels for various port selections.
  1518. X
  1519. XTo   the  application  software,  the  hardware  appears  as   an 
  1520. X8250/16450  type UART.  The application software writes or  reads 
  1521. Xdata  to  and  from registers in the UART.   Table  2  shows  the 
  1522. Xvarious registers and their addresses.  DTR and OUT2 bits in  MCR 
  1523. Xmust be set before communicating with the hardware.  The software 
  1524. Xsends  commands  and  data  to the hardware  by  writing  to  the 
  1525. Xtransmitter  holding  register (THR) in the UART.   Data  can  be 
  1526. Xwritten  to THR when THRE and/or TSRE bits in LSR are  set.    It 
  1527. Xreceives  responses  or  data from the hardware  by  reading  the 
  1528. Xreceive  buffer register (RBR).  Software should first check  the 
  1529. XLSR to see if DR bit is set indicating data is available in  RBR. 
  1530. XInterrupts  can  also  be  used  to  inform  the  software   that 
  1531. Xtransmitter is empty or data is available in the receiver.  Refer 
  1532. Xto  the  8250/16450  data sheet or the  IBM  technical  reference 
  1533. Xmanual  for more information on programming, reading and  writing 
  1534. Xto the UART.
  1535. X
  1536. X2.2 RS232 Standalone version
  1537. X
  1538. XThe UART in the SC11011 controller can be configured by  changing 
  1539. Xone  bit  (Bit3) in the code to present its serial  port  to  the 
  1540. Xoutside  world.   To enable the DTR control function,  the  AT&D2 
  1541. Xcommand must be issued befoer entering the fax mode. 
  1542. X
  1543. XThe  standard 2400 bps modem command set is extended for the  Fax 
  1544. Xapplication using a format of AT#F...  These commands were developed
  1545. Xin accordance with the original set proposed in the TIA T30 committee
  1546. Xin spring of 1989. Sierra is continuing to work with the T29.2 committee
  1547. Xto define teh ultimate standard command set for fax and data modems. 
  1548. X
  1549. XIn  the idle state the hardware is in  the  normal 2400  bps modem
  1550. Xmode.  The UART is programmed at speeds from  300 to 2400 bps to
  1551. Xcommunicate with the hardware. In the fax mode, the DTE is set to 19.2Kbps.
  1552. XFour  states  are defined to allow a clear understanding  of  the 
  1553. Xhardware control process:
  1554. X
  1555. X     1. Modem command mode:   AT commands accepted
  1556. X                              2400 bps max
  1557. X                              modem data mode entered online
  1558. X                              
  1559. X     2. Modem data mode:      +++ escapes to modem command mode
  1560. X                              2400 bps max
  1561. X
  1562. X     3. Fax command mode:     entered from modem command mode 
  1563. X                              with #F1
  1564. X                              19.2 kbps only
  1565. X                         
  1566. X     4. Fax data mode:        commands and data at 19.2kbps only
  1567. X                              return to fax command by:
  1568. X                                   sending command #F 
  1569. X                                   end of call/ call disconnect 
  1570. X                                   dropping DTR 
  1571. X
  1572. XAfter  power-up  the  hardware is in the normal  2400  bps  modem 
  1573. Xcommand mode.
  1574. X
  1575. XA  special command puts the hardware in the Fax mode.    Once  in 
  1576. Xthe  Fax  mode, the UART must be programmed for 19,200  bps  data 
  1577. Xrate, 8 bits and no parity.  This is because the image data  must 
  1578. Xbe  sent  to  the hardware at a rate that  is  faster  than  line 
  1579. Xtransmission  rate.   For 4800 bps synchronous transmission  line 
  1580. Xrate, the UART rate must be at least 9600 bps.  To allow for  the 
  1581. Xfuture accomodation of 9600 bps line transmission rate, the  UART 
  1582. Xspeed  in  Fax mode is fixed at 19,200 bps.   The UART  speed  is 
  1583. Xprogrammed by setting the DLAB bit in the modem control  register 
  1584. X(MCR)  and by writing appropriate values to the  divisor  latches 
  1585. XDLL  and  DLM.   Table 3 provides the DLL,  DLM  speed  selection 
  1586. Xvalues.    Flow  control  (XON/XOFF or RTS/CTS)  is  required  to 
  1587. Xsynchronize  the flow of information between the DTE and the  DCE 
  1588. Xduring image data transmission and HDLC frame reception.  In  the 
  1589. Xdata transmission mode, software must not send data when CTS  bit 
  1590. Xis  off  or  when <XOFF> is received.   Data can  be  sent  after 
  1591. Xreceiving <XON> or when CTS bit is set.
  1592. X  
  1593. X.pa
  1594. X
  1595. X
  1596. X
  1597. XTable 1.       COM port addresses
  1598. X
  1599. XCOM1   3F8 - 3FF    IRQ4
  1600. XCOM2   2F8 - 2FF    IRQ3
  1601. XCOM3   3E8 - 3EF    IRQ4
  1602. XCOM4   2E8 - 2EF    IRQ3
  1603. X
  1604. XTable 2.1       UART registers
  1605. X
  1606. XI/O decode (Hex)
  1607. XCOM1   COM2    COM3    COM4    R/W     DLAB    Register
  1608. X----------------------------------------------------------------
  1609. X3F8    2F8     3E8     2E8      W        0       THR        
  1610. X3F8    2F8     3E8     2E8      R        0       RBR          
  1611. X3F8    2F8     3E8     2E8     R/W       1       DLL
  1612. X3F9    2F9     3E9     2E9     R/W       1       DLM
  1613. X3F9    2F9     3E9     2E9     R/W       0       IER
  1614. X3FA    2FA     3EA     2EA      R        0       IIR
  1615. X3FB    2FB     3EB     2EB     R/W       0       LCR
  1616. X3FC    2FC     3EC     2EC     R/W       0       MCR
  1617. X3FD    2FD     3ED     2ED     R/W       0       LSR   
  1618. X3FE    2FE     3EE     2EE     R/W       0       MSR
  1619. X
  1620. XTable 2.2      Register bit defintions
  1621. X
  1622. XRegister       7     6     5     4     3     2     1     0
  1623. X---------------------------------------------------------------
  1624. XTHR            -------- TRANSMIT DATA (DLAB = 0) ---------
  1625. XRBR            -------- RECEIVE DATA  (DLAB = 0) ---------
  1626. XDLL            ---- DIVISOR LATCH LS BYTE (DLAB = 1) -----         
  1627. XDLM            ---- DIVISOR LATCH MS BYTE (DLAB = 1) -----
  1628. XIER            0    0     0      0    MSI   LSI  THRE   DA
  1629. XIIR            0    0     0      0     0    ID1   ID0   IP/
  1630. XLCR          DLAB   SB    SP    EPS   PEN   STB  WLS1  WLS0
  1631. XMCR            0    0     0    LOOP  OUT2  OUT1   RTS   DTR
  1632. XLSR            0   TSRE  THRE   BI    FE    PE    OR    DR
  1633. XMSR          RLSD   RI    DSR   CTS  DRLS  TERI  DDSR  DCTS  
  1634. X---------------------------------------------------------------
  1635. X
  1636. XTable 3.       Speed selection table 
  1637. X
  1638. XSPEED (BPS)    DLM (HEX)   DLL (HEX)
  1639. X----------------------------------------
  1640. X300               01          80
  1641. X1200              00          60
  1642. X2400              00          30
  1643. X4800              00          18
  1644. X9600              00          0C
  1645. X19200             00          06      
  1646. X----------------------------------------
  1647. X
  1648. X
  1649. X
  1650. X3.0    Command Set
  1651. X
  1652. XExtensions to the Hayes AT command set for Fax mode operation are 
  1653. Xdefined in this section.
  1654. X
  1655. XGeneral
  1656. X
  1657. X1) All extended commands start with the # prefix. This represents 
  1658. Xa  major  change  from previous versions  which  utilized  the  + 
  1659. Xprefix. The change was made to provide upward compatibility  with 
  1660. Xfuture  TIA command sets which are expected to use the +  symbol. 
  1661. XFor the immediate future, the firmware will accept either prefix.
  1662. X
  1663. X2)  All extended commands have only one alpha character  followed 
  1664. Xby a numeric value in the range of decimal 0 to 255.  Value 0 may 
  1665. Xbe omitted.
  1666. X
  1667. X3)  Fax mode assumes XON/XOFF or CTS flow control in  data  mode.  
  1668. X&D2 command must be issued for DTR controlled abort.
  1669. X
  1670. X4) Once the hardware enters the Fax mode, it  will remain in  Fax 
  1671. Xmode ( and accept commands at 19.2 kbps ) until one of  following 
  1672. Xoccurs :
  1673. X
  1674. X       a) software issues a #F request to return to command mode
  1675. X       b) a call disconnect frame is received
  1676. X       c) application software issues an abort by dropping DTR
  1677. X
  1678. XCOMMANDS
  1679. X
  1680. X
  1681. X#Bn     Speed control
  1682. X
  1683. X#B/B0   Reserved         
  1684. X#B1     Reserved
  1685. X#B2     Reserved for V.23
  1686. X#B3     Reserved for V.23
  1687. X#B4    Fax transmission speed of 2400 bps
  1688. X#B5     Fax transmission speed of 4800 bps
  1689. X#B6     Fax transmission speed of 7200 bps
  1690. X#B7     Fax transmission speed of 9600 bps
  1691. X
  1692. XThis  command is used to specify the initial speed at  which  the 
  1693. Xhardware will attempt to connect to the remote Fax machine.   For 
  1694. Xthe SC11046 based hardware this will normally be 4800 bps, so  B5 
  1695. Xcommand  will  be  used.  However, the user  at  his  option  can 
  1696. Xspecify a lower initial speed of 2400 bps by issuing B4.  If  the 
  1697. Xhigher  initial speed is specified, the hardware will attempt  to 
  1698. Xestablish connection at the higher speed and will fallback to the 
  1699. Xlower speed if unsuccessful.
  1700. X
  1701. X
  1702. X
  1703. X
  1704. X
  1705. XEn     Received frame display format selection
  1706. X
  1707. XE/E0   Disable display of received HDLC frames
  1708. XE1     Display frame in binary format
  1709. XE2     Display frame in 2 digit ASCII Hex format
  1710. X
  1711. X
  1712. X
  1713. XFn     Mode control
  1714. X
  1715. XF/F0   Return to normal modem mode (300 to 2400 bps data rate)
  1716. XF1     Enter Fax mode (19,200 bps data rate)
  1717. X
  1718. X
  1719. XKn     DTE flow control
  1720. X
  1721. XK/K0   Disable flow control
  1722. XK3     Enable CTS flow control
  1723. XK4     Enable XON/XOFF flow control
  1724. X
  1725. XMn     Speaker Control
  1726. XM0     Speaker Always Off
  1727. XM1     Speaker Off after Connect Message
  1728. XM2     Speaker Always On
  1729. XM3     Speaker Off during Dial
  1730. X
  1731. XPn     Number of pages to be transmitted (n = 1 to 255)
  1732. X
  1733. X
  1734. XRn     Resolution control
  1735. X
  1736. XR/R0   Send document with normal resolution
  1737. XR1     Send document with fine resolution
  1738. X
  1739. X
  1740. XTn     Test modes
  1741. X
  1742. XT/T0   End test mode
  1743. XT1     Enter  test mode 1.  This mode is used to dial  a  remote       
  1744. X       Fax   machine  and  automatically  send  a  message   stored 
  1745. X       in EPROM.
  1746. X.pa
  1747. X
  1748. X
  1749. XFAX result codes
  1750. X
  1751. XDuring the Fax session the hardware will report the status of the 
  1752. Xcall with result codes.  An action by the software may or may not 
  1753. Xbe necessary depending on the response.
  1754. X
  1755. XAll the normal Hayes result codes will also be reported.
  1756. X
  1757. XVerbose                Digit   Usage
  1758. X
  1759. X
  1760. XCED                      a     Ansertone detected 
  1761. X
  1762. XCFR                      g     Remote machine confirmation to receive
  1763. X
  1764. XCONNECT 2400/FAX         w     Connection speed 2400 bps
  1765. X
  1766. XCONNECT 4800/FAX         x     Connection speed 4800 bps
  1767. X
  1768. XCONNECT 7200/FAX         y     Connection speed 7200 bps
  1769. X
  1770. XCONNECT 9600/FAX         z     Connection speed 9600 bps
  1771. X
  1772. XCRC ERROR                e     Error in received frame
  1773. X
  1774. XCRP                      c     Repeat request
  1775. X
  1776. XCSI                      -     Remote machine Identification
  1777. X
  1778. XDCN                      d     Disconnect
  1779. XDIS                      b     Remote machine capabilities frame
  1780. X
  1781. XFTT                      f     Failure to train
  1782. X
  1783. XINVALID FRAME            i     Received frame is invalid
  1784. X
  1785. X MCF                      m     Message received OK
  1786. X
  1787. XRTN                      h     Message not received OK
  1788. X
  1789. XRTP                      j     Retrain positive
  1790. X.pa
  1791. X
  1792. X
  1793. X4.0    Data format
  1794. X
  1795. XThe  Transmit Subscriber Identification data encoded in the  T.30 
  1796. Xnegotiation  will be taken from the nvram location  Z3. 
  1797. X
  1798. X
  1799. XImage  data  will be in compressed format  with  one  dimensional 
  1800. Xcoding  rules  in accordance with the  CCITT  specification  T.4.  
  1801. XData will be coded assuming the receiving Fax machine is  capable 
  1802. Xof  a  scan time of 0 milliseconds per line.  Each line  of  data 
  1803. Xmust  terminate  with a minimum of 3 bytes of zeroes  before  the  
  1804. XEOL   sequence.  The  zeroes must be byte aligned.  The    software 
  1805. Xwill   detect  the zero  bytes at the end of each line  and  fill 
  1806. Xin  the  required   number   of zeroes  based  on  the  speed  of 
  1807. Xconnection  and the minimum scan time per  line specified by  the 
  1808. Xreceiving  Fax machine.  Data  must  be coded with MSB the  first 
  1809. Xbit   to  be  transmitted from DTE to modem.The modem sends the
  1810. Xdata LSB first to the phone line..    Transmission  of  data    
  1811. Xwill   be synchronized using flow control (XON/XOFF or CTS). After
  1812. Xsending the  last  byte of page data, software will  wait   for a
  1813. Xresponse  from the hardware before issuing a command  or  sending
  1814. Xdata  for the next page.
  1815. X
  1816. X5.0    Example sessions
  1817. X
  1818. XIn  the  following  example sessions, the  response  is  enclosed 
  1819. Xwithin  <> brackets.  The defaults are B3 (4800 bps), P1  (single 
  1820. Xpage), R0 (normal resolution) and T0 (no test mode).    
  1821. X
  1822. XEach  command line terminates with a CRLF, a response begins  and 
  1823. Xterminates with a CRLF.
  1824. X
  1825. Xi) Send 1 page of document with normal resolution
  1826. X
  1827. XCommand                       Response
  1828. X
  1829. XATX4&D2#B3#P1#R0#T0#F1        <OK>      ; Enter Fax mode
  1830. X                              <XOFF> CTS -> 0
  1831. X
  1832. XATDT4082639337                <OK>      ; Dial a Fax machine
  1833. X                                        ; any AT response valid
  1834. X                              <CED>
  1835. X                                        ;  Answertone detected
  1836. X
  1837. X                              <CSI = 408 263 1234>
  1838. X                                        ; Called machine 
  1839. X                                        ; identification
  1840. X                              <DIS>
  1841. X                                        ; Capabilities 
  1842. X                                        ; frame received
  1843. X
  1844. X                              <CFR>
  1845. X                                        ; OK to send page data
  1846. X
  1847. X                              <CONNECT 4800/FAX>
  1848. X                                        ; Connection speed
  1849. X   
  1850. X                              <XON>  CTS -> 1
  1851. X                                        ; Page 1 data is sent 
  1852. X                                        ; using flow control
  1853. X---DATA--SENT---
  1854. X                              <XOFF> CTS -> 0
  1855. X---DATA STOPPED---
  1856. X                              <XON>  CTS -> 1
  1857. X---DATA--SENT---
  1858. X                                        ; No more data for page 1
  1859. X                                        ; tx underflow
  1860. X
  1861. X                              <XOFF> CTS -> 0
  1862. X                              <MCF>
  1863. X                                        ; Page 1 transmission OK
  1864. X          
  1865. X                              <NO CARRIER>
  1866. X                                        ; Call terminated, return to 
  1867. X                                        ; command mode
  1868. X
  1869. Xno new commands 
  1870. Xuntil here
  1871. Xii) Send 2 pages of document with normal resolution
  1872. X
  1873. XCommand                       Response                          
  1874. X
  1875. XATX4&D2#B3#P2#R0#T0#F1                  ; Enter Fax mode
  1876. X                              <XOFF> CTS -> 0
  1877. X                              <OK>
  1878. X
  1879. XATDT4082639337                <OK>      ; Dial a Fax machine
  1880. X                                        ; any AT response valid
  1881. X                              <CED>
  1882. X                                        ; Answertone detected
  1883. X
  1884. X                              <INVALID FRAME> 
  1885. X                                        ; Received frame invalid
  1886. X
  1887. X                              <CSI = 408 263 1234>
  1888. X                                        ; Called machine 
  1889. X                                        ; identification
  1890. X
  1891. X                              <DIS>
  1892. X                                        ; Capabilities 
  1893. X                                        ; frame received
  1894. X
  1895. X
  1896. X                              <CFR>
  1897. X                                        ; OK to send page data
  1898. X                
  1899. X                              <CONNECT 4800/FAX>
  1900. X                                        ; Connection speed
  1901. X
  1902. X                              <XON>  CTS -> 1
  1903. X                                        ; Page 1 data is sent
  1904. X                                        ; using flow control
  1905. X---DATA--SENT---
  1906. X                              <XOFF> CTS -> 0
  1907. X---DATA STOPPED---
  1908. X                              <XON>  CTS -> 1
  1909. X---DATA--SENT---
  1910. X                                        ; No more data for page 1
  1911. X                                        ; tx underrun
  1912. X                              <XOFF> CTS -> 0
  1913. X                              <MCF>
  1914. X                                        ; Page 1 transmission OK
  1915. X                                        
  1916. X                              <XON>  CTS -> 1
  1917. X                                        ; Page 2 Data is sent
  1918. X                                        ; using flow control
  1919. X---DATA--SENT---
  1920. X                              <XOFF> CTS -> 0
  1921. X---DATA STOPPED---
  1922. X                              <XON>  CTS -> 1
  1923. X---DATA--SENT---
  1924. X                                        ; No more data for page 2
  1925. X                                        ; tx underrun
  1926. X
  1927. X                              <XOFF> CTS -> 0
  1928. X                              <MCF>
  1929. X                                        ; Page 2 transmission OK
  1930. X                              <NO CARRIER>
  1931. X                                        ; Call terminated, return to 
  1932. X                                        ; command mode 
  1933. Xno new commands 
  1934. Xuntil here
  1935. X
  1936. X-- 
  1937. XNick Pemberton           uucp: !{lsuc, uunet!mnetor}!aimed!nick
  1938. XAIM, Inc              bus: (416) 429-1085
  1939. XToronto, Ontario, Canada         Home: (416) 690-0647
  1940. X
  1941. X
  1942. END_OF_FILE
  1943.   if test 20046 -ne `wc -c <'writefax.man'`; then
  1944.     echo shar: \"'writefax.man'\" unpacked with wrong size!
  1945.   fi
  1946.   # end of 'writefax.man'
  1947. fi
  1948. echo shar: End of archive 3 \(of 5\).
  1949. cp /dev/null ark3isdone
  1950. MISSING=""
  1951. for I in 1 2 3 4 5 ; do
  1952.     if test ! -f ark${I}isdone ; then
  1953.     MISSING="${MISSING} ${I}"
  1954.     fi
  1955. done
  1956. if test "${MISSING}" = "" ; then
  1957.     echo You have unpacked all 5 archives.
  1958.     rm -f ark[1-9]isdone
  1959. else
  1960.     echo You still must unpack the following archives:
  1961.     echo "        " ${MISSING}
  1962. fi
  1963. exit 0
  1964. exit 0 # Just in case...
  1965.